package com.elephantgreen.business;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Vector;

import com.elephantgreen.common.ElephantgreenCommon;
import com.elephantgreen.common.Euser;
import com.elephantgreen.util.Config;
import com.elephantgreen.xml.EuserXml;

/**
 * Singleton driver class for user authentication and access.
 * 
 * @author Shaminda Samaratunge
 * 
 */
public class EuserDriver {

	private static EuserDriver euserDriver;
	private Vector<ElephantgreenCommon> eUsers;

	private static final String XML_FILE_PROP = "EUSER_FILE";
	private static final String HASH_SECRET_KEY = "HASH_SALT";

	private Euser selectedUser;


	/**
	 * Get instance of the EuserDriver object.
	 * 
	 * @return EuserDriver
	 */
	public static synchronized EuserDriver getInstance() {
		if (euserDriver == null) {
			euserDriver = new EuserDriver();
		}

		return euserDriver;
	}

	/**
	 * Private constructor. External instantiation not possible
	 */
	private EuserDriver() {
		Config c = Config.getInstance();
		EuserXml euXML = new EuserXml(c.readConfig(XML_FILE_PROP),
				"euserDetails");
		eUsers = euXML.getItems();
	}

	/**
	 * Return the hashed password of a user.
	 * 
	 * @param username
	 * @return password
	 */
	public String getPassword(String username) {

		for (ElephantgreenCommon egComm : eUsers) {
			Euser eu = (Euser) egComm;

			if (eu.getUsername().equals(username)) {
				return eu.getPassword();
			}
		}

		return null;
	}

	/**
	 * Authenticate give user.
	 * 
	 * @param username
	 * @param password
	 * @return true if user successfully authenticated.
	 */
	public boolean authenticateUser(String username, String password) {

		selectedUser = null;

		for (ElephantgreenCommon egComm : eUsers) {
			Euser eu = (Euser) egComm;

			// Look for the given user and find the EUser object.
			if (eu.getUsername().equals(username)) {
				selectedUser = eu;
			}
		}

		// Check for the password
		if (selectedUser != null
				&& findMD5String(password, username).equals(
						selectedUser.getPassword())) {
			return true;
		}

		return false;
	}

	/**
	 * Return the MD5 string of a given string.
	 * 
	 * @param text
	 * @return MD5 hash value.
	 */
	private String findMD5String(String text, String username) {

		Config c = Config.getInstance();
		String salt = c.readConfig(HASH_SECRET_KEY);
		text = text + salt.substring(9, 22) + username + salt.substring(3, 13);

		byte[] defaultBytes = text.getBytes();

		try {
			MessageDigest algorithm = MessageDigest.getInstance("MD5");
			algorithm.reset();
			algorithm.update(defaultBytes);
			byte messageDigest[] = algorithm.digest();

			StringBuffer hexString = new StringBuffer();
			for (int i = 0; i < messageDigest.length; i++) {
				String hex = Integer.toHexString(0xFF & messageDigest[i]);
				if (hex.length() == 1)
					hexString.append('0');

				hexString.append(hex);
			}

			return hexString.toString().toUpperCase().trim();

		} catch (NoSuchAlgorithmException nsae) {
			nsae.printStackTrace();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 
	 * @return selected user object
	 */
	public Euser getUser() {
		return selectedUser;
	}

}
